﻿using DX;
using DX.ViewModels;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Tools.ControlHandlers
{

    class OfficeTabPluginHandler
    {

        public OfficeTabPluginHandler(IRouterFactory routFactory, TabControl tab, ContextMenuStrip contextMenu)
        {
            this.routFactory = routFactory;
            this.tab = tab;
            this.contextMenu = contextMenu;

            tab.MouseDown += TabControl_MouseDown;
            tab.MouseDoubleClick += TabControl_MouseDoubleClick;
            contextMenu.VisibleChanged += ContextMenu_VisibleChanged;
            contextMenu.Items.Add("关闭", null, CloseTab);
            contextMenu.Items.Add("独立窗口", null, OpenDialog);
        }


        private readonly IRouterFactory routFactory;
        private readonly TabControl tab;
        private readonly ContextMenuStrip contextMenu;
        private int selectedIndex;
        Action clickAction;
        EventHandler InitClickHandler(PluginProfile pluginProfile, EventHandler propClick)
        {

            EventHandler handler = AllowMultipleCreation(pluginProfile, propClick);
            if (handler != null) return handler;
            handler = SingleCreation(pluginProfile, propClick);
            if (handler != null) return handler;
            return propClick;
        }

        void AllowMultipleClick(PluginProfile pluginProfile)
        {
            CreateNew(pluginProfile);
        }

        private void CreateNew(PluginProfile pluginProfile)
        {
            var viewModelType = Type.GetType(pluginProfile.Type);
            var form = routFactory.GetView(viewModelType) as ViewForm;
            form.TopLevel = false;
            form.FormBorderStyle = FormBorderStyle.None;
            var page = new TabPage
            {
                Text = pluginProfile.Title,

            };

            page.Controls.Add(form);
            tab.TabPages.Add(page);
            form.Show();
            tab.SelectedTab = page;
        }

        EventHandler AllowMultipleCreation(PluginProfile pluginProfile, EventHandler propClick)
        {
            if (!pluginProfile.AllowMultipleCreation)
            {
                return null;
            }
            return (sender, e) =>
             {
                 clickAction = () => AllowMultipleClick(pluginProfile);
                 if (tab.InvokeRequired)
                 {
                     clickAction();
                 }
                 else
                 {
                     tab.Invoke(clickAction);
                 }
                 propClick?.Invoke(sender, e);
             };
        }
        EventHandler SingleCreation(PluginProfile pluginProfile, EventHandler propClick)
        {
            if (pluginProfile.AllowMultipleCreation)
            {
                return null;
            }
            return (sender, e) =>
            {
                clickAction = () => SingleCreationClick(pluginProfile);
                if (tab.InvokeRequired)
                {
                    clickAction();
                }
                else
                {
                    tab.Invoke(clickAction);
                }
                propClick?.Invoke(sender, e);
            };
        }

        void SingleCreationClick(PluginProfile pluginProfile)
        {
            var viewModelType = Type.GetType(pluginProfile.Type);

            var view = routFactory.FindView(viewModelType) as Form;
            if (view == null)
            {
                CreateNew(pluginProfile);
                return;
            }
            if (view.Parent is TabPage page)
            {
                tab.SelectedTab = page;
            }

        }

        public EventHandler Create(PluginProfile pluginProfile, EventHandler click)
        {
            return InitClickHandler(pluginProfile, click);
        }
        private void TabControl_MouseDown(object sender, MouseEventArgs e)
        {

            selectedIndex = -1;
            if (e.Button != MouseButtons.Right || tab.SelectedIndex == -1)
            {
                return;
            }

            if (!Contains(e))
            {
                tab.ContextMenuStrip = null;
                return;
            }
            selectedIndex = tab.SelectedIndex;
            tab.ContextMenuStrip = this.contextMenu;
        }
        private void TabControl_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (tab.SelectedIndex == -1) return;
            if (!Contains(e)) { return; }
            CloseTab(tab.SelectedIndex);
        }
        bool Contains(MouseEventArgs e)
        {
            int tabIndex = tab.SelectedIndex;
            Rectangle tabRect = tab.GetTabRect(tabIndex);
            return tabRect.Contains(e.Location);
        }
        private void CloseTab(int tabIndex)
        {
            if (tabIndex == -1) return;
            var tabpage = tab.TabPages[tabIndex];
            if (tabpage.Controls[0] is ViewForm form && form.ViewModel.CanClose().GetAwaiter().GetResult())
            {
                form.SetViewModelCloseState(true);
                form.Close();
                tab.TabPages.Remove(tabpage);
            }
        }
        void CloseTab(object sender, EventArgs e)
        {
            CloseTab(selectedIndex);
            selectedIndex = -1;
        }

        private void ContextMenu_VisibleChanged(object sender, EventArgs e)
        {
            if (!contextMenu.Visible)
            {
                tab.ContextMenuStrip = null;
            }
        }
        void OpenDialog(object sender, EventArgs e)
        {
            if (selectedIndex == -1) return;
            var tabpage = tab.TabPages[selectedIndex];
            selectedIndex = -1;
            ViewForm newForm = null;
 
            if (tabpage.Controls[0] is UserControlForm form)
            {
             
                form.Parent = null;
                newForm = form.NewForm();

                newForm.SetViewModelCloseState(true);
                form.Close();
                newForm.SetViewModelCloseState(false);
            }
            else if (tabpage.Controls[0] is ViewForm viewform)
            {
              
                viewform.Parent = null;
                newForm = new ViewForm()
                {
                    ViewModelBindingSource = viewform.ViewModelBindingSource,
                    Size = viewform.Size + new Size(10, 50)
                };
        
                newForm.Controls.Add(viewform);


            }
            if (newForm != null)
            {
                routFactory.ApplyGuardClose(newForm.ViewModel, newForm);
                tab.TabPages.Remove(tabpage);
                newForm.Show();
            }

        }

    }


}
